using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using backend.Data;
using backend.Models;
using backend.Models.Dtos;
using Microsoft.EntityFrameworkCore;

namespace backend.Repositories
{
    public class UserRepo : BaseRepo<CampusFacilityRepairManagementDbContext, User>
    {
        private readonly IMapper _mapper;
        public UserRepo(CampusFacilityRepairManagementDbContext context, IMapper mapper) : base(context)
        {
            _mapper = mapper;
        }

        public async Task<User?> GetUserByIdAsync(string uid)
        {
            return await DbSet.FindAsync(uid);
        }

        public async Task<List<User>> GetUsersByPageAsync(int pageIndex, int pageSize, string role)
        {
            if (pageIndex <= 0 || pageSize <= 0)
            {
                throw new ArgumentException("Page and pageSize must be greater than zero.");
            }
            // 使用Skip和Take来实现分页
            var users = await DbSet
                .Where(u => u.URole == role)
                .OrderBy(u => u.UId) // 根据UId排序，也可以根据其他字段排序
                .Skip((pageIndex - 1) * pageSize) // 跳过前 (pageIndex - 1) * pageSize 条记录
                .Take(pageSize) // 获取接下来的 pageSize 条记录
                .ToListAsync(); // 将结果转换为 List<User>

            return users;
        }

        public async Task<int> GetTotalUsersCountAsync(string role)
        {
            return await DbSet.Where(u => u.URole == role).CountAsync();
        }

        public async Task<bool> SaveChangesAsync()
        {
            return await Context.SaveChangesAsync() > 0;
        }

        public async Task<List<UserReturnDto>> GetUserList(string role, int page, int number)
        {
            var users = await DbSet
                .Where(m => m.URole == role)
                .OrderBy(m => m.UId)
                .Skip((page - 1) * number) // 跳过前 (pageIndex - 1) * pageSize 条记录
                .Take(number) // 获取接下来的 pageSize 条记录
                .Select(m => new UserReturnDto
                {
                    UId = m.UId,
                    UName = m.UName,
                    URole = m.URole,
                    UContact = m.UContact,
                })
                .ToListAsync();

            return users;
        }

        public async Task<User> AddUserAsync(UserRegisterDto newUserDto)
        {
            if (newUserDto == null)
            {
                throw new ArgumentNullException(nameof(newUserDto), "New user cannot be null.");
            }

            // Add the new user to the database
            var newUser = _mapper.Map<User>(newUserDto);
            var createdUser = await DbSet.AddAsync(newUser);

            // Return the created user instance
            return createdUser.Entity;
        }

        public async Task<bool> UpdateUserAsync(string uid, UserUpdateDto userToUpdate)
        {
            if (userToUpdate == null)
            {
                throw new ArgumentNullException(nameof(userToUpdate), "user to update cannot be null.");
            }

            // Find the existing maintenance man in the database
            var existingUser = await DbSet.FindAsync(uid);

            if (existingUser == null)
            {
                Console.WriteLine("--------User not found.");
                return false; // The maintenance man does not exist
            }
            _mapper.Map(userToUpdate, existingUser);

            // Save changes to the database
            await SaveChangesAsync();
            return true;
        }

        public async Task<bool> RemoveUserAsync(string uid)
        {
            var user = await GetUserByIdAsync(uid);
            if (user == null)
            {
                return false; // User not found
            }
            if (user.URole == "1" || user.URole == "2") {
                return false; // Cannot remove maintenance and admin users
            }
            // Remove the user from the database
            DbSet.Remove(user);

            // Save changes to the database
            return await SaveChangesAsync();
        }
    }
}